from template import *
import sqlalchemy as sa


def get_engine(uri=None):
    engine = sa.create_engine(uri)    
    return engine

def get_metadata(uri=None):
    engine = get_engine(uri)
    metadata = sa.BoundMetaData(engine)
    return metadata

def get_session(uri=None):
    engine = get_engine(uri)
    return sa.create_session(bind_to=engine)


class AnyUser(object):
    """Any remote user object"""
    pass




class AnyRemoteDbAuthPlugin(TemplateAuthPlugin):
    """a plugin to dig into any remote db"""
    
    def __init__(self, *args, **kwargs):
        super(AnyRemoteDbAuthPlugin, self).__init__(*args, **kwargs)
        # columns that have been added already
        tracked_cols = []
        
        # build primary key columns
        primary_key_cols = []
        for pk in self.config.db.auth_table.primary_key.column:
            dataType = getattr(sa, str(pk.datatype))
            dataValue = str(pk.value)
            tracked_cols.append(str(pk.name))
            col = sa.Column(str(pk.name), dataType(dataValue), primary_key=True, key=getattr(pk, "alt", None))
            primary_key_cols.append(col)
        
        # build other mapped columns
        other_cols = []
        for col in self.config.db.auth_table.mapped_cols.column:
            dataType = getattr(sa, str(col.datatype))
            dataValue = str(col.value)
            if str(col.name) in tracked_cols:
                continue
            else:
                tracked_cols.append(str(col.name))
            sacol = sa.Column(str(col.name), dataType(dataValue), key=getattr(col, "alt", None))
            other_cols.append(sacol)

        all_cols = primary_key_cols + other_cols
        
        self.users_table = sa.Table(str(self.config.db.auth_table.name), get_metadata(str(self.config.db.uri)), *all_cols)
        AnyUser.mapper = sa.mapper(AnyUser, self.users_table)
    
    def authenticate(self, username, password):
        response = False
        session = get_session(str(self.config.db.uri))
        authedUser = session.query(AnyUser).selectfirst(sa.and_(AnyUser.c.username==username, AnyUser.c.password==password))
        if authedUser:
            response = True
        session.close()
        return response
    
